package com.one.group.admin.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import com.one.group.admin.mapper.SpBuildingMapper;
import com.one.group.admin.mapper.SpFloorMapper;
import com.one.group.admin.mapper.SpHouseMapper;
import com.one.group.admin.mapper.SpUnitMapper;
import com.one.group.model.dto.SpBuildingAddDto;
import com.one.group.model.dto.SpBuildingUpdateDto;
import com.one.group.model.entity.SpBuilding;
import com.one.group.model.entity.SpFloor;
import com.one.group.model.entity.SpUnit;
import com.one.group.model.vo.HouseManagementVo;
import com.one.group.service.SpBuildingService;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Objects;

@Service
@DubboService
public class SpBuildingServiceImpl extends ServiceImpl<SpBuildingMapper, SpBuilding> implements SpBuildingService {

    @Autowired
    private SpBuildingMapper spBuildingMapper;
    @Autowired
    private SpHouseMapper spHouseMapper;
    @Autowired
    private SpUnitMapper spUnitMapper;
    @Autowired
    private SpFloorMapper spFloorMapper;
    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Override
    public List<SpBuilding> searchBuildingList(Long cellId) {
        if (ObjectUtil.isEmpty(cellId)){
            // 小区id不能为空
            return List.of();
        }
        List<SpBuilding> spBuildingList = spBuildingMapper.searchBuildingList(cellId);
        return spBuildingList;
    }

    @Override
    public boolean createBuilding(SpBuildingAddDto spBuildingAddDto) {
        // 创建楼栋
        try{
            //设置租户id
            spBuildingAddDto.setTenantId(Convert.toLong(StpUtil.getExtra("tenant_id")));
            spBuildingMapper.createBuilding(spBuildingAddDto);
            //获取自增id
            Long buildingId = spBuildingAddDto.getId();
            //获取添加的楼栋的单元数量
            int unitCount = spBuildingAddDto.getUnitCount();
            //添加单元信息
            for (int i = 0; i < unitCount; i++) {
                SpUnit spUnit = new SpUnit();
                spUnit.setName((i+1)+"单元");
                spUnit.setBuildingId(buildingId);
                spUnitMapper.insert(spUnit, true);
            }
            //获取添加的楼栋的楼层数量
            int floorCount = spBuildingAddDto.getFloorCount();
            //添加楼层信息
            for (int i = 0; i < floorCount; i++) {
                SpFloor spFloor = new SpFloor();
                spFloor.setName((i+1)+"楼层");
                spFloor.setBuildingId(buildingId);
                spFloorMapper.insert(spFloor, true);
            }
            rabbitTemplate.setMessageConverter(new Jackson2JsonMessageConverter());
            rabbitTemplate.convertAndSend("gxa.direct","buildingUpdate",spBuildingAddDto.getBuildingtypeId());
            return true;
        }catch (Exception e){
            return false;
        }

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateBuilding(SpBuildingUpdateDto spBuildingUpdateDto) {
        //获取原数据
        SpBuilding spBuilding = getById(spBuildingUpdateDto.getId());
        if (spBuilding == null){
            return false;
        }
        spBuilding.setName(spBuildingUpdateDto.getName());
        spBuilding.setOrientation(spBuildingUpdateDto.getOrientation());
        spBuilding.setHeightM(spBuildingUpdateDto.getHeightM());
        spBuilding.setStructure(spBuildingUpdateDto.getStructure());
        //判断是否需要更新单元数
        if (!Objects.equals(spBuilding.getUnitCount(), spBuildingUpdateDto.getUnitCount())){
            // 生成需要操作的单元id列表
            int proUnitCount = spBuilding.getUnitCount();
            int newUnitCount = spBuildingUpdateDto.getUnitCount();
            //id减少
            if (proUnitCount > newUnitCount){
                for (int i = proUnitCount; i > newUnitCount; i--) {
                    //获取单元id
                    QueryWrapper queryWrapper = new QueryWrapper();
                    queryWrapper.eq(SpUnit::getBuildingId,spBuilding.getId());
                    queryWrapper.eq(SpUnit::getName,i+"单元");
                    SpUnit spUnit = spUnitMapper.selectOneByQuery(queryWrapper);
                    if (spUnit == null){
                        throw new RuntimeException("单元数据异常");
                    }
                    //删除单元
                    if(!spUnitMapper.mydeleteById(spUnit.getId())){
                        throw new RuntimeException("单元数据异常");
                    }
                }
            }
            //id增加
                for (int i = proUnitCount; i < newUnitCount; i++) {
                    SpUnit spUnit = new SpUnit();
                    spUnit.setName((i+1)+"单元");
                    spUnit.setBuildingId(spBuilding.getId());
                    if (spUnitMapper.insert(spUnit, true)==0){
                        throw new RuntimeException("单元数据异常");
                    }
                }
                spBuilding.setUnitCount(spBuildingUpdateDto.getUnitCount());
        }
        //判断是否需要更新楼层数
        if (!Objects.equals(spBuilding.getFloorCount(), spBuildingUpdateDto.getFloorCount())){
            // 获取需要操作的楼层id列表
            int proFloorCount = spBuilding.getFloorCount();
            int newFloorCount = spBuildingUpdateDto.getFloorCount();
            //id减少
            if (proFloorCount > newFloorCount){
                for (int i = proFloorCount; i > newFloorCount; i--) {
                    //获取楼层id
                    QueryWrapper queryWrapper = new QueryWrapper();
                    queryWrapper.eq(SpFloor::getBuildingId,spBuilding.getId());
                    queryWrapper.eq(SpFloor::getName,i+"楼层");
                    SpFloor spFloor = spFloorMapper.selectOneByQuery(queryWrapper);
                    if (spFloor == null){
                        throw new RuntimeException("楼层数据异常");
                    }
                    if(!spFloorMapper.mydeleteById(spFloor.getId())){
                        throw new RuntimeException("楼层数据异常");
                    }
                }
            }
            //id增加
                for (int i = proFloorCount; i < newFloorCount; i++) {
                    SpFloor spFloor = new SpFloor();
                    spFloor.setName((i+1)+"楼层");
                    spFloor.setBuildingId(spBuilding.getId());
                    if (spFloorMapper.insert(spFloor, true)==0){
                        throw new RuntimeException("楼层数据异常");
                    }
                }
                spBuilding.setFloorCount(spBuildingUpdateDto.getFloorCount());

        }
        SpBuilding spBuilding1 = getMapper().selectOneById(spBuildingUpdateDto.getId());
        rabbitTemplate.setMessageConverter(new Jackson2JsonMessageConverter());
        rabbitTemplate.convertAndSend("gxa.direct","buildingUpdate",spBuilding1.getBuildingtypeId());
        return updateById(spBuilding,true);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean myRemoveById(Long id) {
        //获取租户id
        Long tenant_id = Convert.toLong(StpUtil.getExtra("tenant_id"));
        //检查是否存在相关的数据
        List<HouseManagementVo> houseManagementVos = spHouseMapper.getHouseManagementList(id,tenant_id);
        spUnitMapper.deleteByQuery(new QueryWrapper().eq(SpUnit::getBuildingId,id));
        spFloorMapper.deleteByQuery(new QueryWrapper().eq(SpFloor::getBuildingId,id));
        if (!houseManagementVos.isEmpty()){
            throw new RuntimeException("该楼有房屋存在");
        }
        SpBuilding spBuilding1 = getMapper().selectOneById(id);
        rabbitTemplate.setMessageConverter(new Jackson2JsonMessageConverter());
        rabbitTemplate.convertAndSend("gxa.direct","buildingUpdate",spBuilding1.getBuildingtypeId());
        return removeById(id);

    }
}
